package com.yundasys.lab10designpattern.singleton;

import java.io.Serializable;

/**
 * 第5种 基于 volatile 的双重检查锁定的解决方案
 *
 * @author jiangta
 * @version 1.0
 * @date 2021/4/14 10:22 上午
 */
public class DoubleCheckSingleton implements Serializable {
    private volatile static DoubleCheckSingleton instance;
    public static DoubleCheckSingleton getInstance() {
        if(instance == null) {
            synchronized (DoubleCheckSingleton.class) {
                if(instance == null) {
                    //双重检查存在的意义在于可能会有多个线程进入第一个判断，然后竞争同步锁，线程A得到了同步锁，创建了一个Singleton实例，赋值给instance，然后释放同步锁，此时线程B获得同步锁，又会创建一个Singleton实例，造成初始化覆盖。
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }

    /**
     * 通过实现readResolve方法，ObjectInputStream实例对象在调用readObject()方法进行反序列化时，就会判断相应的类是否实现了readResolve()方法，如果实现了，就会调用readResolve()方法返回一个对象作为反序列化的结果，而不是去创建一个新的对象。
     * @return
     */
    private Object readResolve() {
        return instance;
    }
}
